package scparser.factory.primitiveFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import lib.common.Constants;
import model.Scene;
import model.primitive.Plane;
import model.primitive.Primitive;
import scparser.ParserHelper;

public class PlaneFactory extends PrimitiveFactory {
	private List<Point3d> p;
	private Vector3d n;
	
	public PlaneFactory(Scene scene) {
		super.scene = scene;
		this.p = new ArrayList<Point3d>();
	}

	@Override
	public Primitive create(List<String> block) throws FactoryException {
		String line = null;
		Iterator<String> it = block.iterator();

		try {
			while (it.hasNext()) {
				line = it.next().trim();
				if (line.endsWith(Constants.S_CLOSE)) {
					break;
				} else if (line.startsWith("name")) {
					this.name = ParserHelper.takeString(line, "name");
				} else if (line.startsWith("shader")) {
					String shaderName = ParserHelper.takeString(line, "shader");
					if ((this.shader = super.getShader(shaderName)) == null) {
						throw new FactoryException("shader " + shaderName + " not found");
					}			
				} else if (line.startsWith("shader")) {
					String shaderName = ParserHelper.takeString(line, "shader");
					if ((this.shader = super.getShader(shaderName)) == null) {
						throw new FactoryException("shader " + shaderName + " not found");
					}			
				} else if (line.startsWith("p")) {
					p.add(ParserHelper.takePoint(line, "p"));					
				} else if (line.startsWith("n")) {
					this.n = new Vector3d(ParserHelper.takePoint(line, "n"));
				} else if (line.startsWith("transform")) {
					if (line.endsWith(Constants.S_CLOSE)) {
						parseTransform(line);
					} else {
						parseTransform(it);
					}
				} 
			}
			
			Plane np = null;
			switch (p.size()) {
				case 1: np=new Plane(this.shader, this.name, p.get(0), this.n); break;
				case 3: np=new Plane(this.shader, this.name, p.get(0), p.get(1), p.get(2)); break;	
				default: throw new FactoryException("Wrong number of points in plane " + this.name);
			}
			
			return transformPresent ? transform(np) : np;
			
		} catch (IOException e) {
			throw new FactoryException(e.getMessage());
		} catch (NumberFormatException e) {
			throw new FactoryException(e.getMessage());
		}
		
	}
}
